home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / snd_sun.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  4KB  |  219 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <stdlib.h>
  23. #include <sys/types.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/mman.h>
  26. #include <sys/shm.h>
  27. #include <sys/wait.h>
  28. #include <stdio.h>
  29. #include <sys/audioio.h>
  30. #include <errno.h>
  31. #include "quakedef.h"
  32.  
  33. int audio_fd;
  34. int snd_inited;
  35.  
  36. static int bufpos;
  37. static int wbufp;
  38. static audio_info_t info;
  39.  
  40. #define BUFFER_SIZE        8192
  41.  
  42. unsigned char dma_buffer[BUFFER_SIZE];
  43. unsigned char pend_buffer[BUFFER_SIZE];
  44. int pending;
  45.  
  46. static int lastwrite = 0;
  47.  
  48. qboolean SNDDMA_Init(void)
  49. {
  50.     int rc;
  51.     int fmt;
  52.     int tmp;
  53.     int i;
  54.     char *s;
  55.     int caps;
  56.  
  57.     if (snd_inited) {
  58.         printf("Sound already init'd\n");
  59.         return;
  60.     }
  61.  
  62.     shm = &sn;
  63.     shm->splitbuffer = 0;
  64.  
  65.     audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY);
  66.  
  67.     if (audio_fd < 0) {
  68.         if (errno == EBUSY) {
  69.             Con_Printf("Audio device is being used by another process\n");
  70.         }
  71.         perror("/dev/audio");
  72.         Con_Printf("Could not open /dev/audio\n");
  73.         return (0);
  74.     }
  75.  
  76.     if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  77.         perror("/dev/audio");
  78.         Con_Printf("Could not communicate with audio device.\n");
  79.         close(audio_fd);
  80.         return 0;
  81.     }
  82.  
  83.     //
  84.     // set to nonblock
  85.     //
  86.     if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
  87.         perror("/dev/audio");
  88.         close(audio_fd);
  89.         return 0;
  90.     }
  91.  
  92.     AUDIO_INITINFO(&info);
  93.  
  94.     shm->speed = 11025;
  95.  
  96.     // try 16 bit stereo
  97.     info.play.encoding = AUDIO_ENCODING_LINEAR;
  98.     info.play.sample_rate = 11025;
  99.     info.play.channels = 2;
  100.     info.play.precision = 16;
  101.  
  102.     if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
  103.         info.play.encoding = AUDIO_ENCODING_LINEAR;
  104.         info.play.sample_rate = 11025;
  105.         info.play.channels = 1;
  106.         info.play.precision = 16;
  107.         if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
  108.             Con_Printf("Incapable sound hardware.\n");
  109.             close(audio_fd);
  110.             return 0;
  111.         }
  112.         Con_Printf("16 bit mono sound initialized\n");
  113.         shm->samplebits = 16;
  114.         shm->channels = 1;
  115.     } else { // 16 bit stereo
  116.         Con_Printf("16 bit stereo sound initialized\n");
  117.         shm->samplebits = 16;
  118.         shm->channels = 2;
  119.     }
  120.  
  121.     shm->soundalive = true;
  122.     shm->samples = sizeof(dma_buffer) / (shm->samplebits/8);
  123.     shm->samplepos = 0;
  124.     shm->submission_chunk = 1;
  125.     shm->buffer = (unsigned char *)dma_buffer;
  126.  
  127.     snd_inited = 1;
  128.  
  129.     return 1;
  130. }
  131.  
  132. int SNDDMA_GetDMAPos(void)
  133. {
  134.     if (!snd_inited)
  135.         return (0);
  136.  
  137.     if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  138.         perror("/dev/audio");
  139.         Con_Printf("Could not communicate with audio device.\n");
  140.         close(audio_fd);
  141.         snd_inited = 0;
  142.         return (0);
  143.     }
  144.  
  145.     return ((info.play.samples*shm->channels) % shm->samples);
  146. }
  147.  
  148. int SNDDMA_GetSamples(void)
  149. {
  150.     if (!snd_inited)
  151.         return (0);
  152.  
  153.     if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
  154.         perror("/dev/audio");
  155.         Con_Printf("Could not communicate with audio device.\n");
  156.         close(audio_fd);
  157.         snd_inited = 0;
  158.         return (0);
  159.     }
  160.  
  161.     return info.play.samples;
  162. }
  163.  
  164. void SNDDMA_Shutdown(void)
  165. {
  166.     if (snd_inited) {
  167.         close(audio_fd);
  168.         snd_inited = 0;
  169.     }
  170. }
  171.  
  172. /*
  173. ==============
  174. SNDDMA_Submit
  175.  
  176. Send sound to device if buffer isn't really the dma buffer
  177. ===============
  178. */
  179. void SNDDMA_Submit(void)
  180. {
  181.     int samps;
  182.     int bsize;
  183.     int bytes, b;
  184.     static unsigned char writebuf[1024];
  185.     unsigned char *p;
  186.     int idx;
  187.     int stop = paintedtime;
  188.     extern int soundtime;
  189.  
  190.     if (paintedtime < wbufp)
  191.         wbufp = 0; // reset
  192.  
  193.     bsize = shm->channels * (shm->samplebits/8);
  194.     bytes = (paintedtime - wbufp) * bsize;
  195.  
  196.     if (!bytes)
  197.         return;
  198.  
  199.     if (bytes > sizeof(writebuf)) {
  200.         bytes = sizeof(writebuf);
  201.         stop = wbufp + bytes/bsize;
  202.     }
  203.  
  204.     p = writebuf;
  205.     idx = (wbufp*bsize) & (BUFFER_SIZE - 1);
  206.  
  207.     for (b = bytes; b; b--) {
  208.         *p++ = dma_buffer[idx];
  209.         idx = (idx + 1) & (BUFFER_SIZE - 1);
  210.     }
  211.  
  212.     wbufp = stop;
  213.  
  214.     if (write(audio_fd, writebuf, bytes) < bytes)
  215.         printf("audio can't keep up!\n");
  216.  
  217. }
  218.  
  219.